#pragma once

#include <iostream>
#include <string>
#include <memory>
#include <vector>
#include <chrono>
#include <iomanip>
#include <map>
#include <mutex>
#include <sstream>
#include <fstream> 
#include <cstring> 

#include "../mytcp.h"
#include "user.h"

class ChatRoom;
class UserManager;
class CommandProcessor;

/*=================================================客户端连接类=================================================*/
// 客户端连接类，封装单个客户端的连接信息和其专属的处理逻辑
class ClientConnection : public std::enable_shared_from_this<ClientConnection>//这样的继承是为了让 ClientConnection 类的对象能够在自身方法中安全地获取一个指向自己的 std::shared_ptr。
{
private:
    std::shared_ptr<Socket> client_socket; // 客户端的Socket对象
    std::shared_ptr<User> logged_in_user; // 如果客户端已登录，则指向其对应的User对象
    bool is_logged_in; // 标记客户端是否已登录
public:
    ClientConnection(std::shared_ptr<Socket> sock); // 构造函数

    std::shared_ptr<Socket> getclientSocket();//获取连接的客户端的socket对象，命令处理类那边要用
    int getSocketFd() const; // 获取客户端的Socket文件描述符
    void send(const std::string& message); // 向该客户端发送消息

    void setLoggedInUser(std::shared_ptr<User> user); // 设置登录用户
    std::shared_ptr<User> getLoggedInUser() const; // 获取登录用户
    bool isLoggedIn() const; // 检查客户端是否已登录
};

/*=================================================用户管理类=================================================*/
// 用户管理类，负责所有注册用户的信息管理
class UserManager
{
private:
    std::string user_data_file; // 存储用户数据的文件路径
    std::map<std::string, User> registered_users; // 存储已注册用户的map，键为用户名，值为User对象
    std::mutex users_mutex; // 用于保护registered_users的并发访问
    int next_user_id; // 下一个可用的用户ID

    void loadUsers(); // 从文件加载所有用户数据
    void saveUsers(); // 将用户数据保存到文件

public:
    UserManager(const std::string& filename); // 构造的时候就加载数据

    bool registerUser(const std::string& name, const std::string& password, const std::string& describe); // 注册新用户
    std::shared_ptr<User> loginUser(const std::string& name, const std::string& password); // 验证用户登录
    std::shared_ptr<User> getUserByName(const std::string& name); // 根据用户名查找User对象
};

/*=================================================聊天室类=================================================*/
// 聊天室类，管理所有在线客户端连接，并负责广播消息
class ChatRoom
{
private:
    std::map<int, std::shared_ptr<ClientConnection>> online_clients; // fd -> ClientConnection，存储所有在线客户端
    std::mutex clients_mutex; // 用于保护online_clients的并发访问，防止对online_clients属性产生资源竞争的问题

public:
    void addClient(std::shared_ptr<ClientConnection> client); // 添加一个新连接的客户端到在线列表
    void removeClient(int fd); // 从在线列表中移除一个客户端
    void broadcastMessage(const std::string& message, int exclude_fd = -1); // 向所有在线客户端广播消息
    void sendMessageToUser(const std::string& username, const std::string& message); // 向指定用户发送私聊消息
    std::vector<std::string> getOnlineUsernames(); // 获取当前所有在线用户的用户名列表
};

/*=================================================命令处理类=================================================*/
// 命令处理器类，解析客户端发送的命令消息，并触发相应的处理逻辑
class CommandProcessor
{
public:
    void myregister(std::shared_ptr<ClientConnection> sender, std::istringstream& iss, UserManager& user_manager);
    void mylogin(std::shared_ptr<ClientConnection> sender, std::istringstream& iss, UserManager& user_manager, ChatRoom& chat_room);
    void mymsg(std::shared_ptr<ClientConnection> sender, std::istringstream& iss, ChatRoom& chat_room);
    void myupload(std::shared_ptr<ClientConnection> sender, std::istringstream& iss);
    void mydownload(std::shared_ptr<ClientConnection> sender, std::istringstream& iss);

    void processCommand(std::shared_ptr<ClientConnection> sender, const std::string& command_message,
        UserManager& user_manager, ChatRoom& chat_room, EpollET& epoll_instance); // 处理客户端命令
};

/*=================================================服务器主类=================================================*/
// 服务器主类，协调各个组件的工作
class Server
{
private:
    std::shared_ptr<Socket> server_socket; // 服务器监听Socket
    std::shared_ptr<EpollET> epoll_instance; // Epoll实例
    std::shared_ptr<UserManager> user_manager; // 用户管理器实例
    std::shared_ptr<ChatRoom> chat_room; // 聊天室实例
    std::shared_ptr<CommandProcessor> command_processor; // 命令处理器实例
    std::map<int, std::shared_ptr<ClientConnection>> active_connections; // fd -> ClientConnection，存储所有活跃的客户端连接

    std::string getCurrentTime(); // 获取当前时间字符串
    std::string formatChatMessage(const std::string& username, const std::string& message); // 格式化聊天消息

public:
    Server(const char* ip, uint16_t port, const std::string& user_data_file); // 构造函数
    void start(); // 启动服务器，进入Epoll事件循环
};